//  -------------------- iSharePoint -------------------- //
// 
//  Company:	IT Complex, LLC
//  Project:	Smart.Common
//  File name:	FormsFormatter.cs
//  Developer:	Solomatov Igor
//  Created:	15.04.2012
// 
//  -------------------- iSharePoint -------------------- //

using System;
using Smart.Common.Rules;

namespace Smart.Common.Forms
{
	/// <summary>
	/// Forms formatter (create form from definition)
	/// </summary>
	public abstract class FormsFormatter
	{
		/// <summary>
		/// Forms context
		/// </summary>
		public FormsContext Ctx { get; set; }

		/// <summary>
		/// Instantiate form in container
		/// </summary>
		public abstract void InstantiateFormInContainer();

		/// <summary>
		/// Load current values from container
		/// </summary>
		public abstract void LoadValuesAfterInstantiate();

		/// <summary>
		/// Process form after loading with values
		/// </summary>
		public abstract void ProcessFormAfterLoad();

		/// <summary>
		/// Process form rules
		/// </summary>
		public virtual void ProcessFormRules()
		{
			Ctx.ActionRulesService = GetFormRulesService();

			if (Ctx.ActionRulesService == null)
				return;

			var ri = GetFormRulesInstance();

			Ctx.Form.FormChanged |= Ctx.ActionRulesService.Execute(ri);
		}

		/// <summary>
		/// Return new RulesService
		/// </summary>
		/// <returns></returns>
		public virtual IRulesService GetFormRulesService()
		{
			if (Ctx.ActionRulesServiceName.IsNullOrEmpty())
				throw new ArgumentNullException("Ctx.ActionRulesServiceName");

			return SPServices.RulesFactory.GetService(Ctx.ActionRulesServiceName);
		}

		/// <summary>
		/// Return new RulesInstance
		/// </summary>
		public virtual FormsActionRulesInstance GetFormRulesInstance()
		{
			return new FormsActionRulesInstance(Ctx.Form.Rules, Ctx);
		}

		/// <summary>
		/// Process form after rule processing
		/// </summary>
		public abstract void ProcessFormAfterRules();

		/// <summary>
		/// Save form values to entity
		/// </summary>
		public abstract void SaveValues();

		/// <summary>
		/// Return current language code id
		/// </summary>
		public abstract int GetCurrentLCID();

		/// <summary>
		/// Detect form action rules service name
		/// </summary>
		public virtual string DetectFormActionRulesServiceName()
		{
			return Const.Forms.DefaultRulesServiceName;
		}

		/// <summary>
		/// Perform action from rules on form
		/// </summary>
		public virtual bool PerformAction(string actionName, string[] actionArgs)
		{
			bool handled;

			var res = Ctx.Service.PerformAction(actionName, actionArgs, out handled);

			if (!handled)
				throw new NotSupportedException(actionName);

			return res;
		}

		/// <summary>
		/// Execute rule condition function
		/// </summary>
		public virtual bool ExecuteFunction(string functionName, string[] functionArgs)
		{
			bool handled;

			var res = Ctx.Service.ExecuteFunction(functionName, functionArgs, out handled);

			if (!handled)
				throw new NotSupportedException(functionName);

			return res;
		}

		/// <summary>
		/// Forms formatter (create form from definition)
		/// </summary>
		protected FormsFormatter(FormsContext ctx)
		{
			Ctx = ctx;
		}
	}
}